package org.szy.core.common.interceptor;//package org.szy.core.common.interceptor;

import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import org.noear.solon.annotation.Component;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Handler;
import org.noear.solon.core.route.RouterInterceptor;
import org.noear.solon.core.route.RouterInterceptorChain;
import org.noear.solon.core.util.RunUtil;
import org.noear.solon.validation.ValidatorException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.szy.core.common.entity.R;
import org.szy.core.common.exception.BaseException;
import org.szy.core.common.exception.BaseExceptionCode;
import org.szy.core.common.uilts.ReqUtil;
import org.szy.core.event.monitor.handle.UserOnlineRouterHandle;

/**
 * 全局路由器拦截器
 *
 * @author 孙志阳
 * @date 2023-02-10
 * @since 1.0.0
 **/
@Component
public class GlobalRouterInterceptor implements RouterInterceptor {

    private static final Logger log = LoggerFactory.getLogger(GlobalRouterInterceptor.class);

    boolean useUserOnline = false;

    {
        try {
            Class.forName("org.szy.monitor.entity.UserOnline");
            useUserOnline = true;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void doIntercept(Context ctx, Handler mainHandler, RouterInterceptorChain chain) throws Throwable {
        log.info("请求地址:{}", ctx.url());
        try {
            chain.doIntercept(ctx, mainHandler);
            if (!ctx.getHandled()) {
                if (ReqUtil.isAjax(ctx)) {
                    ctx.render(BaseExceptionCode.CODE_4001011);
                } else {
                    log.error("未找到页面，跳转到404页，请求地址：{}", ctx.path());
                    ctx.forward("/error/404");
                }
            }
        } catch (BaseException e) {
            ctx.render(R.fail(e.getMsg()));
        } catch (ValidatorException e) {
            //验证器异常
            ctx.render(R.fail(e.getMessage()));
        } catch (Throwable e) {
            log.error("Throwable", e);
            if (e instanceof Exception) {
                ctx.render(R.fail(e.getMessage()));
            } else {
                ctx.render(R.fail("服务器异常"));
            }
        }
        if (useUserOnline) {
            try {
                if (StpUtil.isLogin()) {
                    SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
                    SaSession saSession = StpUtil.getTokenSession();
                    RunUtil.async(() -> UserOnlineRouterHandle.doIntercept(tokenInfo, saSession));
                }
            } catch (Exception ignored) {

            }
        }
    }

    @Override
    public Object postResult(Context ctx, Object result) throws Throwable {
        return RouterInterceptor.super.postResult(ctx, result);
    }
}
